using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Sinacor.Infra.Service.Validation;
using Sinacor.Infra.Service.Common;
using Sinacor.Service.Infra.AuthorizationService.BusinessEntity;
using Sinacor.Infra.Common.Exceptions;

namespace Sinacor.Service.Infra.AuthorizationService.BusinessLogic
{
    /// <summary>
    /// Business Logic Policy
    /// </summary>
    public class Policy : BaseBusinessLogic
    {
        #region Propriedades
        private ResourceAccess.Policy _policyRa = new Sinacor.Service.Infra.AuthorizationService.ResourceAccess.Policy();
        #endregion

        #region Construtor
        public Policy()
            : base()
        {

        }
        #endregion

        #region Métodos

        /// <summary>
        /// Método InsertPolicy
        /// </summary>
        public BusinessEntity.Policy InsertPolicy(BusinessEntity.Policy request)
        {
            if (request == null)
                throw new ValidationException(945);

            SinacorValidation validation = new SinacorValidation();

            validation.AddValidation<Sinacor.Service.Infra.AuthorizationService.BusinessEntity.Policy>(request,RuleSetConstants.INSERT);

            validation.Validate();

            validation = null;

            return _policyRa.InsertPolicy(request);
        }

        /// <summary>
        /// Método UpdatePolicy
        /// </summary>
        public void UpdatePolicy(BusinessEntity.Policy request)
        {            
            if (request == null)
                throw new ValidationException(946);

            SinacorValidation validation = new SinacorValidation();

            validation.AddValidation<Sinacor.Service.Infra.AuthorizationService.BusinessEntity.Policy>(request, RuleSetConstants.UPDATE);

            validation.Validate();

            validation = null;

            _policyRa.UpdatePolicy(request);
        }

        /// <summary>
        /// Método DeletePolicy
        /// </summary>
        public void DeletePolicy(BusinessEntity.Policy request)
        {
            if (request == null)
                throw new ValidationException(947);

            SinacorValidation validation = new SinacorValidation();

            validation.AddValidation<Sinacor.Service.Infra.AuthorizationService.BusinessEntity.Policy>(request,RuleSetConstants.DELETE);

            validation.Validate();

            validation = null;

            VerifyDependencies(request);

            _policyRa.DeletePolicy(request);
        }

        /// <summary>
        /// Metodo responsavel por verificar as dependecias da entidade Policy
        /// Por hora esta sendo verificado se ha alguma BehaviorPolicy Associada
        /// </summary>
        /// <param name="request"></param>
        private void VerifyDependencies(BusinessEntity.Policy request)
        {
            BusinessEntity.BehaviorPolicy behaviorPolicyBE = new BusinessEntity.BehaviorPolicy(); 
            BusinessLogic.BehaviorPolicy behaviorPolicyBL = new BehaviorPolicy();

            behaviorPolicyBE.AssociatedPolicy = request;

            if (behaviorPolicyBL.RetrieveBehaviorPolicies(behaviorPolicyBE).Count > 0)
                throw new BusinessException(950);

        }

        /// <summary>
        /// Método RetrievePolicy
        /// </summary>
        public BusinessEntity.Policy RetrievePolicy(BusinessEntity.Policy request)
        {
            if (request == null)
                throw new ValidationException(948);

            BusinessEntity.Policy response = new BusinessEntity.Policy();
            SinacorValidation validation = new SinacorValidation();

            validation.AddValidation<Sinacor.Service.Infra.AuthorizationService.BusinessEntity.Policy>(request, RuleSetConstants.SELECTONE);

            validation.Validate();

            validation = null;

            response = _policyRa.RetrievePolicy(request);
            return response;
        }

        /// <summary>
        /// Método RetrievePolicies
        /// </summary>
        public List<BusinessEntity.Policy> RetrievePolicies(BusinessEntity.Policy request)
        {
            if (request == null)
                throw new ValidationException(949);
            
            List<BusinessEntity.Policy> response = new List<BusinessEntity.Policy>();

            response = _policyRa.RetrievePolicies(request);

            if (response == null)
                response = new List<BusinessEntity.Policy>();

            return response;
        }

        #endregion


        /// <summary>
        /// Retornar as Policies as quais o usuario nao tem acesso
        /// </summary>
        /// <param name="userAssociatedBehaviorPolicies"></param>
        internal List<BusinessEntity.Policy> RetrieveUserNotAssociatedPolicies(List<BusinessEntity.Policy> userAssociatedPolicies)
        {        
            List<BusinessEntity.Policy> response = _policyRa.RetrieveUserNotAssociatedPolicies(userAssociatedPolicies);

            if (response == null)
                response = new List<Sinacor.Service.Infra.AuthorizationService.BusinessEntity.Policy>();

            return response;
        }
    }
}
